//
// Created by ta&to on 2022/8/22.
//

#ifndef TPSERVER_TP_THREAD_H
#define TPSERVER_TP_THREAD_H
#include <pthread.h>
#include <atomicvar.h>
#include <malloc.h>
#include <errno.h>
#include "tcp_alloc.h"
#include "tcp_time.h"
#include "tcp_string.h"
#include "tree.h"
#include "container.h"
#include "tcp_atomic.h"

// 线程因子 当任务数与线程因子的乘积依然大于线程总数时 调整线程数量
#define THREAD_FACTOR  0.55
// 线程空闲时间超过该值时线程将递减
#define THREAD_RESIDUE_TIMES 5
//初始线程数
#define THREAD_INIT_NUMBER 50
// 最大线程数
#define THREAD_MAX_NUMBER  100
// 最小存活线程数
#define THREAD_MIN_NUMBER  20
//任务队列允许的最大等待处理的任务数
#define THREAD_TASK_MAX_QUEUE -1

#define Thread_Pool_Sync() pthread_join(Thread_Pool_Monitor(&tpt), NULL)
/**
    void ttask(thread_pool_t *tpt, thread_task_t *task){
        while(1){
            sleep(30);
            printf("-------------4-1-----------\n");
        }

    }
    int main()
    {
        setbuf(stdout, NULL);       // 正式使用时请去掉该代码
        thread_pool_t tpt;
        Thread_Pool_Init(&tpt);
        tpt.initthreads = 500;
        tpt.maxthreads = 1000;
        tpt.minthreads = 1;
        Thread_Task_Post(&tpt, &ttask);
        Thread_Pool_Commit(&tpt);
        Thread_Pool_Sync();
        return 0;  // Never returns
    }
 */
#define thread_err 0
#define thread_ok  1


typedef struct{
    pthread_t *tid;
    pthread_attr_t *pattr;
    void (*func) (void *);
    void *args;
} tcp_thread_t;

enum run_state{
    TP_THREAD_STATE_NEW,
    TP_THREAD_STATE_RUNNABLE,
    TP_THREAD_STATE_BLOCKED,
    TP_THREAD_STATE_WAITING,
    TP_THREAD_STATE_TIME_WAITING,
    TP_THREAD_STATE_TERMINATED
};

extern volatile long taskid;

typedef struct thread_container_s thread_container_t;
typedef struct thread_task_s thread_task_t;
typedef struct thread_pool_s thread_pool_t;

typedef void (*handle)(void *);
struct thread_container_s{
    pthread_t tid;
    pthread_t pid;
    time_t freeresiduetimeout;   // 空闲开始时间戳
    enum run_state runstate;
};

typedef struct {
    thread_task_t        *first;
    thread_task_t       **last;
    long                count;
} thread_task_queue_t;

struct thread_pool_s{
    char *name;
    int threads;                        // 实际线程数
    int initthreads;                    // 初始线程数
    int minthreads;                     // 最小线程数
    int maxthreads;                     // 最大线程数
    int freethreads;                    // 空闲线程数
    long threadresiduetimes;            // 线程空闲阈值
    linklist_t list_thread;             // 线程索引
    Leader leader_thread;               // 线程容器
    thread_task_queue_t queue;          // 任务队列
    int max_queue;                      // 允许的最大任务数 -1 表示无限制
    int waiting;                        // 等待的任务数
    pthread_mutex_t mtx;                // 全局锁 只为线程等待使用
    pthread_mutex_t tlock;              // 全局锁 用于线程创建同步
    pthread_rwlock_t thread_rwlock;     // 线程池全局读写锁
    pthread_rwlock_t task_rwlock;       // 任务队列全局读写锁
    pthread_cond_t cond;
};

typedef struct {
    int i;
    void * args;
    thread_task_t *ttt;
    thread_pool_t *tpt;
    thread_container_t *tct;
} thread_task_args_t;

struct thread_task_s{
    thread_task_t *next;
    long taskid;
    void *ctx;
    void (*handler)(void *, thread_task_args_t *);
};
/**
 * 创建一个任务队列
 * @param ttq 任务队列
 */
void Thread_Create_task_queue(thread_task_queue_t *ttq);
/**
 * 像队列中插入一个任务
 * @param ttq
 * @param handler
 */
int Thread_Task_Post(thread_pool_t* tpt, void (*handler)(void *data), void *args);
/**
 * 从队列中弹出一个任务
 * @param tpt
 * @return
 */
thread_task_t* Thread_Task_Pop(thread_pool_t* tpt);
/*
 * 销毁任务
 */
int Thread_Task_Destry(thread_pool_t* tpt, thread_task_t *ttt);
/**
 * 提交任务
 * @param tp
 * @return
 */
int Thread_Pool_Commit(thread_pool_t *tp);
/*
 * 获取任务数
 */
void Thread_Pool_Init(thread_pool_t* tpt);
/**
 * 实现自动监控
 * @param tpt
 * @return
 */
pthread_t Thread_Pool_Monitor(thread_pool_t *tpt);

#endif //TPSERVER_TP_THREAD_H
